﻿/*
' DotNetNuke® - http://www.dotnetnuke.com
' Copyright (c) 2002-2009
' by DotNetNuke Corporation
'
' Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated 
' documentation files (the "Software"), to deal in the Software without restriction, including without limitation 
' the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and 
' to permit persons to whom the Software is furnished to do so, subject to the following conditions:
'
' The above copyright notice and this permission notice shall be included in all copies or substantial portions 
' of the Software.
'
' THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED 
' TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 
' THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF 
' CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 
' DEALINGS IN THE SOFTWARE.
*/

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using DotNetNuke.Tests.UI.WatiN.Common;
using System.Configuration;
using System.Web.Configuration;
using DotNetNuke.Tests.UI.WatiN.Utilities;
using System.IO;
using Gallio.Framework.Pattern;
using WatiN.Core;
using MbUnit.Framework;
using DotNetNuke.Tests.UI.WatiN.Common.WatiNObjects;

namespace DotNetNuke.Tests.UI.WatiN.RegressionTests
{
    public class RTBase : TestBase
    {
        protected WatiNBase baseWatinObject;
        protected IE ieInstance;
        private string databasePath;
        private string siteZipFileName;
        private string upgradeZipFileName;
        private string installZipFileName;
        private string upgradeVersion;
        private string upgradeType;
        private string upgradeName;
        private bool isUpgrade;
        private bool isProTest;

        protected virtual string ApplicationName
        {
            get
            {
                string appName;
                if (isUpgrade)
                {
                    appName = upgradeName;
                }
                else
                {
                    appName = String.Format("DNN_{0}_{1}", (IsUpgrade) ? UpgradeVersion.ToString(3).Replace(".", "") : TestVersion.Replace(".", ""), VersionType);
                }
                return appName;
            }
        }

        protected RTContext RTContext
        {
            get
            {
                RTContext context = null;
                PatternTestInstanceState testState = PatternTestInstanceState.FromContext(TestContext);
                if (testState.TestArguments != null && testState.TestArguments.Length > 1)
                {
                    string version = testState.TestArguments[0] as string;
                    string type = testState.TestArguments[1] as string;
                    context = new RTContext(version, type);
                }
                return context;
            }
        }

        protected string DatabaseName
        {
            get 
            {
                string DBName;
                if (isUpgrade)
                {
                    DBName = String.Format("DNN_{0}_{1}", upgradeVersion, upgradeType);
                }
                else
                {
                    DBName = String.Format("DNN_{0}", TestVersion.Replace(".", "")); 
                }
                return DBName;
            }
        }

        protected string DatabaseServer
        {
            get { return TestEnvironment.DatabaseServer; }
        }

        protected string DatabasePath
        {
            get
            {
                string physicalPath = Path.Combine(TestEnvironment.DatabasePath, "RT");
                physicalPath = Path.Combine(physicalPath, ApplicationName);
                return (!IsUpgrade) ? physicalPath : String.Format("{0}_{1}", physicalPath, SiteType);
            }
        }

        protected string TestFilesPath
        {
            get 
            {
                return TestEnvironment.TestFilesPath;
            }
        }

       protected bool IsUpgrade
        {
            get { return (RTContext == null) ? false : RTContext.IsUpgrade; }
        }

        protected string PhysicalPath
        {
            get
            {
                string physicalPath = Path.Combine(TestEnvironment.WebsitePath, "RT");
                physicalPath = Path.Combine(physicalPath, ApplicationName);
                if (isUpgrade)
                {
                   physicalPath = String.Format("{0}_{1}", physicalPath, upgradeType);
                }
                return physicalPath;                
            }
        }

        protected string ForumPackagePath
        {
            get
            {
                return Path.Combine(TestEnvironment.TestFilesPath, TestEnvironment.ForumPackageName);
            }
        }

        protected override string SiteURL
        {
            get
            {
                return String.Format("http://localhost/{0}", ApplicationName);
            }
        }

        protected  new string VersionType
        {
            get
            {
                string versionType = ConfigurationManager.AppSettings["VersionType"]; 
                if(isProTest && versionType.CompareTo("Professional") != 0)
                {
                    versionType = "Professional";
                }
                return versionType;
            }
        }

        protected virtual string SiteType
        {
            get { return (RTContext == null) ? String.Empty : RTContext.Type; }
        }

        protected string CapturePath
        {
            get
            {
                string physicalPath = Path.Combine(TestEnvironment.ScreenCapturePath, "RT");
                physicalPath = Path.Combine(physicalPath, ApplicationName);
                return (!isUpgrade) ? physicalPath : String.Format("{0}_{1}", physicalPath, upgradeType);
            }
        }


        protected Version UpgradeVersion
        {
            get { return (RTContext == null) ? null : RTContext.UpgradeVersion; }
        }

        #region Private Helper Methods

        protected void SetConnectionString(string applicationPath, string databaseName, string userName, string password)
        {
            string connString = String.Format("Server={0};Database={1};uid={2};pwd={3};",
                                                                TestEnvironment.DatabaseServer,
                                                                databaseName,
                                                                userName,
                                                                password);

            Configuration configuration = WebConfigurationManager.OpenWebConfiguration("/" + applicationPath);

            //Setup Connection String
            ConnectionStringsSection connectionStringsSection = configuration.GetSection("connectionStrings") as ConnectionStringsSection;
            ConnectionStringSettingsCollection connectionStrings = connectionStringsSection.ConnectionStrings;
            ConnectionStringSettings connectionString = connectionStrings["SiteSqlServer"];
            connectionString.ConnectionString = connString;

            AppSettingsSection appSettingsSection = configuration.GetSection("appSettings") as AppSettingsSection; ;
            appSettingsSection.Settings["SiteSqlServer"].Value = connString;

            configuration.Save();
        }

        protected void SetUpTest()
        {
            //Setup the Website             
            SetUpWebSite(PhysicalPath, TestUsers.DBUser.UserName, TestUsers.DBUser.Password);

            //Attach the Database
            DatabaseManager.DropDatabase(DatabaseName);
            DatabaseManager.CopyAndAttachDatabase(TestContext, DatabasePath, DatabaseName);
            //Ensure the correct user is the Databases owner.
            DatabaseManager.SetDatabaseOwner(DatabaseName, TestUsers.DBUser.UserName);

            // Open a new Internet Explorer window and navigate to the website
            ieInstance = WatiNUtil.OpenIEInstance(SiteURL, SilentMode, IETimeOut, AutoCloseIE, AutoMovePointer);
            baseWatinObject = new WatiNBase(ieInstance, SiteURL, DatabaseName);
        }

        protected void SetUpProTestForInstall()
        {
            isUpgrade = false;
            isProTest = true;
            //Make sure that the target folder is empty
            if (Directory.Exists(PhysicalPath))
            {
                Directory.Delete(PhysicalPath, true);
            }

            installZipFileName = String.Format("DotNetNuke_Professional_{0}_Install.zip", TestVersion);

            //First Unzip Package to Website location
            ZipManager.ExtractZip(Path.Combine(TestEnvironment.PackagePath, installZipFileName), PhysicalPath);

            //Next Setup Website 
            SetUpWebSite(PhysicalPath, TestUsers.DBUser.UserName, TestUsers.DBUser.Password);

            //Create Database
            DatabaseManager.CreateDatabase(TestContext, DatabaseName);

            //Add User
            DatabaseManager.AddUser(DatabaseName, TestUsers.DBUser.UserName, TestUsers.DBUser.Password, new[] { "db_owner" });

            // Open a new Internet Explorer window and navigate to the website
            ieInstance = WatiNUtil.OpenIEInstance(SiteURL, SilentMode, IETimeOut, AutoCloseIE, AutoMovePointer);

            //Assert that we get the Install page
            Assert.IsTrue(ieInstance.Span(Find.ById("wizInstall_lblStep0Title")).Exists);
        }


        protected void SetUpTestForInstall()
        {
            isUpgrade = false;
            if(VersionType.CompareTo("Community") == 0)
            {
                isProTest = false;
            }
            
            //Make sure that the target folder is empty
            if (Directory.Exists(PhysicalPath))
            {
                Directory.Delete(PhysicalPath, true);
            }

            installZipFileName = String.Format("DotNetNuke_{0}_{1}_Install.zip", VersionType, TestVersion);

            //First Unzip Package to Website location
            ZipManager.ExtractZip(Path.Combine(TestEnvironment.PackagePath, installZipFileName), PhysicalPath);

            //Next Setup Website 
            SetUpWebSite(PhysicalPath, TestUsers.DBUser.UserName, TestUsers.DBUser.Password);
            IISManager.SetApplicationPool(ApplicationName, "DefaultAppPool");

            //Create Database
            DatabaseManager.CreateDatabase(TestContext, DatabaseName);

            //Add User
            DatabaseManager.AddUser(DatabaseName, TestUsers.DBUser.UserName, TestUsers.DBUser.Password, new[] { "db_owner" });

            // Open a new Internet Explorer window and navigate to the website
            ieInstance = WatiNUtil.OpenIEInstance(SiteURL, SilentMode, IETimeOut, AutoCloseIE, AutoMovePointer);

            //Assert that we get the Install page
            Assert.IsTrue(ieInstance.Span(Find.ById("wizInstall_lblStep0Title")).Exists);
        }

        protected void RunAutoInstall()
        {
            WizardPage wizardPage = new WizardPage(ieInstance, SiteURL, 0, DatabaseName);
            WatiNBase homePage = new WatiNBase(ieInstance, SiteURL, DatabaseName);
            if (!Directory.Exists(CapturePath + @"\Installs\"))
            {
                Directory.CreateDirectory(CapturePath + @"\Installs");
            }

            //Act
            //Initial Install page - select install method
            wizardPage.SelectInstallMethod("Auto");
            wizardPage.Next.Click();

            //Wait until install completes
            if (!ieInstance.Text.Contains("Installing DotNetNuke"))
            {
                if (File.Exists(CapturePath + @"\Installs\AutoError.jpg"))
                {
                    File.Delete(CapturePath + @"\Installs\AutoError.jpg");
                }
                ieInstance.CaptureWebPageToFile(CapturePath + @"\Installs\AutoError.jpg");
            }
            Assert.IsTrue(ieInstance.Text.Contains("Installing DotNetNuke"));
            ieInstance.WaitUntilContainsText("Click Here To Access Your Portal");
            if (File.Exists(CapturePath + @"\Installs\Auto.jpg"))
            {
                File.Delete(CapturePath + @"\Installs\Auto.jpg");
            }
            if (ieInstance.Text.Contains("Error") || ieInstance.Text.Contains("Failure"))
            {
                Gallio.Framework.TestLog.Write(@"An Error has occurred during the installation however the tests may continue. For more information on the error view the screenshot for this test under Tests\Screen Captures.");
            }

            //Click on link to go to Home Page
            ieInstance.Link(Find.ByText("Click Here To Access Your Portal")).Click();

            //Assert
            Assert.IsTrue(homePage.LogoLink.Exists);

            //Run some database updates
            string sqlUpdateString = @"UPDATE Users SET UpdatePassword='False'";
            string sqlAdminEmailUpdateString = @"UPDATE Users SET Email='" + TestUsers.Admin.Email + "' WHERE Username = 'admin'";
            string sqlHostEmailUpdateString = @"UPDATE Users SET Email='" + TestUsers.Host.Email + "' WHERE Username = 'host'";

            try
            {
                //Set the admin and host users update password value to false
                DatabaseManager.ExecuteSQLUpdateStringOnDatabase(DatabaseName, TestUsers.DBUser.UserName, TestUsers.DBUser.Password,
                                                            sqlUpdateString);
                //Change the Admins EmailAddress to the EmailAddress listed for the admin in TestUsers
                DatabaseManager.ExecuteSQLUpdateStringOnDatabase(DatabaseName, TestUsers.DBUser.UserName, TestUsers.DBUser.Password,
                                                            sqlAdminEmailUpdateString);
                //Change the Hosts EmailAddress to the EmailAddress listed for the host in TestUsers
                DatabaseManager.ExecuteSQLUpdateStringOnDatabase(DatabaseName, TestUsers.DBUser.UserName, TestUsers.DBUser.Password,
                                                            sqlHostEmailUpdateString);
            }
            catch (Exception e)
            {
                Console.WriteLine(e);
            }
        }

        protected void SetUpSiteForUpgrade()
        {            
            //Make sure that the target folder is empty
            if (Directory.Exists(PhysicalPath))
            {
                Directory.Delete(PhysicalPath, true);
            }

            siteZipFileName = String.Format("DNN_{0}_{1}.zip", upgradeVersion, upgradeType);

            upgradeZipFileName = String.Format("DotNetNuke_{0}_{1}_Upgrade.zip", VersionType, TestVersion);

            //First Unzip Site Package to Website location
            ZipManager.ExtractZip(Path.Combine(TestEnvironment.PackagePath, siteZipFileName), Path.Combine(TestEnvironment.WebsitePath, "RT"));

            //Next Create Website 
            SetUpWebSite(PhysicalPath, TestUsers.DBUser.UserName, TestUsers.DBUser.Password);
            if (Convert.ToInt32(UpgradeVersion) < 480)
            {
                //Use classic pool
                IISManager.SetApplicationPool(ApplicationName, "Classic .NET AppPool");
            }

            //Attach Database
            databasePath = DatabaseManager.GetDataBaseFileName(TestContext, DatabaseName, ".mdf");
            File.Copy(Path.Combine(PhysicalPath, "App_Data\\Database.mdf"), databasePath, true);
            DatabaseManager.AttachDatabase(DatabaseName, databasePath);

            //Add User
            DatabaseManager.AddUser(DatabaseName, TestUsers.DBUser.UserName, TestUsers.DBUser.Password, new[] { "db_owner" });

            //Run some database updates
            string sqlAdminEmailUpdateString = @"UPDATE Users SET Email='" + TestUsers.Admin.Email + "' WHERE Username = 'admin'";
            try
            {
                //Change the Admins EmailAddress to the EmailAddress listed for the admin in TestUsers
                DatabaseManager.ExecuteSQLUpdateStringOnDatabase(DatabaseName, TestUsers.DBUser.UserName, TestUsers.DBUser.Password,
                                                            sqlAdminEmailUpdateString);
            }
            catch (Exception e)
            {
                Console.WriteLine(e);
            }

            // Open a new Internet Explorer window and navigate to the website
            ieInstance = WatiNUtil.OpenIEInstance(SiteURL, SilentMode, IETimeOut, AutoCloseIE, AutoMovePointer);
            baseWatinObject = new WatiNBase(ieInstance, SiteURL, DatabaseName);
        }

        protected void RunCommunity523Upgrade()
        {
            //Unzip Upgrade Package to Website location
            ZipManager.ExtractZip(Path.Combine(TestEnvironment.TestFilesPath, "DotNetNuke_Community_05.02.03_Upgrade.zip"), PhysicalPath);

            //Open a new Internet Explorer window and navigate to the website
            ieInstance = WatiNUtil.OpenIEInstance(SiteURL, SilentMode, IETimeOut, AutoCloseIE, AutoMovePointer);
            WatiNBase homePage = new WatiNBase(ieInstance, SiteURL, DatabaseName);
            if (!Directory.Exists(CapturePath))
            {
                Directory.CreateDirectory(CapturePath);
            }

            //Wait until install completes
            if (!ieInstance.Text.Contains("Upgrading DotNetNuke"))
            {
                if (File.Exists(CapturePath + @"\UpgradeNotStarted.jpg"))
                {
                    File.Delete(CapturePath + @"\UpgradeNotStarted.jpg");
                }
                ieInstance.CaptureWebPageToFile(CapturePath + @"\UpgradeNotStarted.jpg");

            }
            Assert.IsTrue(ieInstance.Text.Contains("Upgrading DotNetNuke"), @"The upgade was not started. For more information on the error view the screenshot for this test under Tests\Screen Shots.");
            ieInstance.WaitUntilContainsText("Click Here To Access Your Portal", IETimeOut);
            if (File.Exists(CapturePath + @"\Upgrade.jpg"))
            {
                File.Delete(CapturePath + @"\Upgrade.jpg");
            }
            ieInstance.CaptureWebPageToFile(CapturePath + @"\Upgrade.jpg");
            if (ieInstance.Text.Contains("Error") || ieInstance.Text.Contains("Failure"))
            {
                Gallio.Framework.TestLog.WriteHighlighted("WARNING:");
                Gallio.Framework.TestLog.Write(@" An Error has occurred during the upgrade however the tests may continue. For more information on the error view the screenshot for this test under Tests\Screen Captures.");
            }

            //Click on link to go to Home Page
            ieInstance.Link(Find.ByText("Click Here To Access Your Portal")).Click();
        }

        protected void RunUpgrade()
        {
            //Unzip Upgrade Package to Website location
            ZipManager.ExtractZip(Path.Combine(TestEnvironment.PackagePath, upgradeZipFileName), PhysicalPath);

            //Open a new Internet Explorer window and navigate to the website
            ieInstance = WatiNUtil.OpenIEInstance(SiteURL, SilentMode, IETimeOut, AutoCloseIE, AutoMovePointer);
            WatiNBase homePage = new WatiNBase(ieInstance, SiteURL, DatabaseName);
            if (!Directory.Exists(CapturePath))
            {
                Directory.CreateDirectory(CapturePath);
            }

            //Wait until install completes
            if (!ieInstance.Text.Contains("Upgrading DotNetNuke"))
            {
                if (File.Exists(CapturePath + @"\UpgradeNotStarted.jpg"))
                {
                    File.Delete(CapturePath + @"\UpgradeNotStarted.jpg");
                }
                ieInstance.CaptureWebPageToFile(CapturePath + @"\UpgradeNotStarted.jpg");

            }
            Assert.IsTrue(ieInstance.Text.Contains("Upgrading DotNetNuke"), @"The upgade was not started. For more information on the error view the screenshot for this test under Tests\Screen Shots.");
            ieInstance.WaitUntilContainsText("Click Here To Access Your Portal", IETimeOut);
            if (File.Exists(CapturePath + @"\Upgrade.jpg"))
            {
                File.Delete(CapturePath + @"\Upgrade.jpg");
            }
            ieInstance.CaptureWebPageToFile(CapturePath + @"\Upgrade.jpg");
            if (ieInstance.Text.Contains("Error") || ieInstance.Text.Contains("Failure"))
            {
                Gallio.Framework.TestLog.WriteHighlighted("WARNING:");
                Gallio.Framework.TestLog.Write(@" An Error has occurred during the upgrade however the tests may continue. For more information on the error view the screenshot for this test under Tests\Screen Captures.");
            }

            //Click on link to go to Home Page
            ieInstance.Link(Find.ByText("Click Here To Access Your Portal")).Click();
        }

        protected void SetUpWebSite(string physicalPath, string userName, string password)
        {
            IISManager.RecycleApplicationPool(ApplicationName);
            IISManager.CreateIISApplication(ApplicationName, physicalPath);

            //Set web.config connection settings
            SetConnectionString(ApplicationName, DatabaseName, userName, password);
        }

        protected void TearDownTest()
        {
            //Make sure user is logged out
            ieInstance.GoTo(SiteURL + "/LogOff.aspx");

            //Shut down Ie
            WatiNUtil.CloseIEInstance(ieInstance);

            //Recycle IIS App Pool
            IISManager.RecycleApplicationPool(ApplicationName);

            //Drop Database
            DatabaseManager.DropDatabase(DatabaseName);
        }


        #endregion

        #region Public Methods

        public void SetUpgradeVersionAndType(string version, string siteType)
        {
            isUpgrade = true;
            upgradeVersion = version;
            upgradeType = siteType;

            upgradeName = String.Format("DNN_{0}", version);
        }

        #endregion

    }

}
